import org.codehaus.groovy.grails.plugins.springsecurity.Secured
//import org.springframework.security.providers.UsernamePasswordAuthenticationToken as AuthToken
//import org.springframework.security.context.SecurityContextHolder as SCH
import com.st.utils.DataList
import grails.converters.JSON

/**
 * Person controller.
 */
@Secured(['ROLE_ADMIN', 'ROLE_POWER_USER'])
class PersonController extends AbstractSecurity {

    // the delete, save and update actions only accept POST requests
    static Map allowedMethods = [delete: 'POST', save: 'POST', update: 'POST']

    /** VIEWS **/
    // List Views
    def list = {
//        println "params for person list = " + params
        return [type:params.type?:"all", companyId:params.companyId]
    }

    // Show Views
    def show = {
        if (!params.id || (!isPowerUser() && (getUserId() != params.id))) {
            params.id = getUserId()
        }

        def person = Person.get(params.id)
        if (!person) {
            flash.message = "The person with the id $params.id was not found."
            redirect action:list
            return
        }
        return [person:person]
    }

    def showRep = {
//        println "show rep params = " + params
        if (!isPowerUser()) {
            params.id = getUserId()
        }
//        println "show rep params = " + params

//        println "rep for id = " + Representative.get(params.id)
//        println "person for rep id = " + Representative.get(params.id).person
        def person = Representative.get(params.id).person
        if (!person) {
            flash.message = "The person with the id $params.id was not found."
            redirect action:list
            return
        }
        render view:'show', model:[person:person]
    }

    // Create/Edit Views
    @Secured(['ROLE_ADMIN', 'ROLE_POWER_USER'])
    def create = {
        if (!params.companyId) {
            flash.message = "Currently it is only possible to create a profile if it is associated with a company."
            redirect controller:'company', action:'list'
            return
        }

        def company = Company.get(params.companyId)
        if (!company) {
            flash.message = "There was no company found to create the person for."
            redirect controller:'company', action:list
            return
        }
        return [person:new Person(phone:company.phone), company:company, returnAction:params.returnAction, returnController:params.returnController]
    }

    def edit = {
        if (!params.id || (!isPowerUser() && (getUserId() != params.id))) {
            params.id = getUserId()
        }

        def person = Person.get(params.id)

        if (params.type && params.type == "Reps") {
            def user = User.findByPerson(person)
            if (!user) {
// need an error message here.
            }
            redirect(controller:'user', action:edit, params:[id:user.id])
        }

        if (!person) {
            flash.message = "The person with the id $params.id was not found."
            redirect action:list
            return
        }
        return [person:person]
    }

//    def editList = {
////        println "returnto = " + params.returnTo
//        def company = Company.get(params.companyId)
//        if(!company) {
//            flash.message = "Company not found with id ${params.id}"
//            redirect action:list
//        } else {
//            return [company:company, people:company."${params.type.toLowerCase()}", type:params.type, returnController:params.returnController, returnAction:params.returnAction]
//        }
//    }

    /** ACTIONS **/
    // Save/Update/Delete Actions
    def cancel = {
        def returnController = params.returnController?:"company"
        def returnAction = params.returnAction?:"list"
        def returnId = params.companyId?:""
        redirect controller:returnController, action:returnAction, id:returnId
    }

    def save = {
        // person title cannot = "null" this should not be needed because it
        // should convert the title correctly though it is not.
        if (params.person.title == '') {
            params.person.title = null
        }

        def person = new Person(params.person)

        def company
        if (params.companyId) {
            company = Company.get(params.companyId)
        }

        if (!person.hasErrors()) {
            Person.count()
            if (!person.save()) {
                flash.message = "There was an error saving the profile."
                render view:'create', model:[person:person, company:company, returnAction:params.returnAction, returnController:params.returnController]
                return
            } else {
                flash.message = "The person was created successfully."
                returnTo()
                if (company) {
                    company.addToContacts(person)
                }
            }
        } else {
            flash.message = "The person was not created."
            render view:'create', model:[person:person, company:company, returnAction:params.returnAction, returnController:params.returnController]
        }
    }

    def update = {
//        println "params in update person = " + params
        def person = new Person(params.person)

        if (person.save()) {
            flash.message = "Person updated successfully."
            redirect action:show, id:person.id
        } else {
            flash.message = "There was an error updating the person."
            render view:'edit', model:[person:person]
        }
    }

    def addToCompany = {
//        println "add person to company = " + params
        def company = Company.get(params.id)
        def person = Person.get(params.person_id)

        if (company && person) {
//            println "we have a good company and person."
            company."addTo${params.type}" person
//            println "person = " + person
//            println "company = " + company
        } else {
            flash.message = """The data provided is invalid. This should not
                    happen there is an error with the application please inform
                    the admin of this error."""
        }
        render view:'_peopleList', model:[companyId:company.id, type:params.type]
    }

    def returnTo = {
//        println "params = " + params
        redirect controller:params.returnController, action:params.returnAction, id:params.companyId
    }

    /** JSON DATA **/
    def listPeopleAsJSON = {
        // Getting the required values and setting up defaults for the default
        // people list table.
        def sortIndex = params.sidx ?: 'lastName'
        def sortOrder = params.sord ?: 'asc'
        def maxRows = Integer.valueOf(params.rows)
        def currentPage = Integer.valueOf(params.page) ?: 1
        def rowOffset = currentPage == 1 ? 0 : (currentPage - 1) * maxRows
        def searchValue = params.searchValue
        def people
        def count
        def company

        if (params.companyId) {
            println "looking for people in company " + params.companyId
            company = Company.findById(params.companyId)
            if (params.type == "Reps") {
                println "Looking for reps for the company."
                people = company.reps.person
            } else {
                println "looking for other contacts for the company."
                people = company.contacts
            }
            count = people.size()
        } else {
            println "didn't find a company id"
            // Search for the company.
            people = Person.createCriteria().list(max:maxRows, offset:rowOffset) {
                // Searching for the criteria in the fields indicated below.
                // Using ilike to perform a case insensitive search.
                if (searchValue && searchValue.trim().length() > 1) {
                    or {
                        ilike("firstName", "%${searchValue}%")
                        ilike("lastName", "%${searchValue}%")
                        ilike("phone", "%${searchValue}%")
                        ilike("email", "%${searchValue}%")
                    }
                }

                // Set the order.
                order(sortIndex, sortOrder).ignoreCase()
            }
            count = people.totalCount
        }

        // Create the cells string to be converted to json later.
        def jsonCells = people.collect {
            [cell: [
                    it.title==null?"":it.title.toString(),
                    it.firstName,
                    it.lastName,
                    it.phone,
                    it.email,
                    it.notes
                ],
                id: it.id]
        }

        // Create the rest of the json string to be used.
        def results = [rows:jsonCells, page:currentPage,
                       records:count,
                       total:Math.ceil(count / maxRows)]

        // If the results are null we set the results to "".
        if (!results) {
            results = ""
        }
        render results as JSON
    }

    def listAsJSON = {
        def people
        if (params.companyId != "null") {
            people = Company.get(params.companyId)."${params.type.toLowerCase()}"
        } else {
            people = Person.list(max:params.max, offset:params.offset)
        }
        people = people.collect {[
            id:it.id,
            dataUrl:g.createLink(controller:'person', action:'show') + "/$it.id",
            title:it.user.title?:"",
            firstName:it.user.firstName,
            lastName:it.user.lastName,
            role:it.roles?:"None",
            phone:it.user.phone,
            email:it.user.email?:"",
            notes:it.user.notes?:""
        ]}

        people.sort {first, second ->
            def left
            def right
            if (params.order == 'desc') {
                left = second
                right = first
            } else {
                left = first
                right = second
            }
            left."$params.sort" <=> right."$params.sort"
        }
        render DataList.createListWithSize(people.size(), people) as JSON
    }

    def listRepsNotInCompanyForACAsJSON = {
        def companyReps = Company.get(params.companyId).reps as List
        def reps = Representative.list()
        if (companyReps) {
            reps.removeAll(companyReps)
        }
        reps = reps.collect {
            [id:it.id, name:"${it.user.name}"]
        }
        render DataList.createList(reps) as JSON
    }

    /** UTILITIES **/
}
